<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>AGiXT WebSocket Conversation Stream Test</title>
    <style>
      body {
        font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
        max-width: 1200px;
        margin: 0 auto;
        padding: 20px;
        background-color: #f5f5f5;
      }
      .container {
        background: white;
        border-radius: 8px;
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
        padding: 20px;
        margin-bottom: 20px;
      }
      .form-group {
        margin-bottom: 15px;
      }
      label {
        display: block;
        margin-bottom: 5px;
        font-weight: bold;
        color: #333;
      }
      input,
      button {
        padding: 10px;
        border: 1px solid #ddd;
        border-radius: 4px;
        font-size: 14px;
      }
      input {
        width: 100%;
        box-sizing: border-box;
      }
      button {
        background-color: #007cba;
        color: white;
        border: none;
        cursor: pointer;
        margin-right: 10px;
      }
      button:hover {
        background-color: #005a8b;
      }
      button:disabled {
        background-color: #ccc;
        cursor: not-allowed;
      }
      .status {
        padding: 10px;
        border-radius: 4px;
        margin: 10px 0;
        font-weight: bold;
      }
      .status.connected {
        background-color: #d4edda;
        color: #155724;
        border: 1px solid #c3e6cb;
      }
      .status.disconnected {
        background-color: #f8d7da;
        color: #721c24;
        border: 1px solid #f5c6cb;
      }
      .status.connecting {
        background-color: #fff3cd;
        color: #856404;
        border: 1px solid #ffeaa7;
      }
      .messages {
        height: 400px;
        overflow-y: auto;
        border: 1px solid #ddd;
        padding: 10px;
        background-color: #fafafa;
        font-family: "Courier New", monospace;
        font-size: 12px;
      }
      .message {
        margin-bottom: 10px;
        padding: 8px;
        border-radius: 4px;
        border-left: 4px solid #007cba;
        background-color: white;
      }
      .message.error {
        border-left-color: #dc3545;
        background-color: #fff5f5;
      }
      .message.heartbeat {
        border-left-color: #28a745;
        background-color: #f8fff8;
      }
      .message.connected {
        border-left-color: #17a2b8;
        background-color: #f0f9ff;
      }
      .timestamp {
        color: #666;
        font-size: 11px;
      }
      .stats {
        display: flex;
        gap: 20px;
        margin: 10px 0;
      }
      .stat {
        background: #e9ecef;
        padding: 10px;
        border-radius: 4px;
        text-align: center;
        flex: 1;
      }
      .stat-value {
        font-size: 24px;
        font-weight: bold;
        color: #007cba;
      }
      .stat-label {
        font-size: 12px;
        color: #666;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <h1>🔌 AGiXT WebSocket Conversation Stream Test</h1>
      <p>Test the real-time conversation streaming WebSocket endpoint.</p>

      <div class="form-group">
        <label for="serverUrl">Server URL:</label>
        <input
          type="text"
          id="serverUrl"
          value="localhost:7437"
          placeholder="localhost:7437"
        />
      </div>

      <div class="form-group">
        <label for="token">Authentication Token:</label>
        <input type="password" id="token" placeholder="Bearer token" />
      </div>

      <div class="form-group">
        <label for="conversationId">Conversation ID:</label>
        <input
          type="text"
          id="conversationId"
          placeholder="conversation-uuid"
        />
      </div>

      <button id="connectBtn" onclick="connect()">Connect</button>
      <button id="disconnectBtn" onclick="disconnect()" disabled>
        Disconnect
      </button>
      <button onclick="clearMessages()">Clear Messages</button>

      <div id="status" class="status disconnected">Disconnected</div>

      <div class="stats">
        <div class="stat">
          <div class="stat-value" id="messageCount">0</div>
          <div class="stat-label">Messages</div>
        </div>
        <div class="stat">
          <div class="stat-value" id="errorCount">0</div>
          <div class="stat-label">Errors</div>
        </div>
        <div class="stat">
          <div class="stat-value" id="uptime">00:00</div>
          <div class="stat-label">Uptime</div>
        </div>
      </div>
    </div>

    <div class="container">
      <h2>📨 Messages</h2>
      <div id="messages" class="messages"></div>
    </div>

    <script>
      let ws = null;
      let messageCount = 0;
      let errorCount = 0;
      let connectTime = null;
      let uptimeInterval = null;

      function updateStatus(status, message) {
        const statusEl = document.getElementById("status");
        statusEl.className = `status ${status}`;
        statusEl.textContent = message;
      }

      function addMessage(type, content, isError = false, isHeartbeat = false) {
        const messagesEl = document.getElementById("messages");
        const messageEl = document.createElement("div");

        let className = "message";
        if (isError) className += " error";
        else if (isHeartbeat) className += " heartbeat";
        else if (type === "connected") className += " connected";

        messageEl.className = className;

        const timestamp = new Date().toLocaleTimeString();
        messageEl.innerHTML = `
                <div class="timestamp">[${timestamp}] ${type.toUpperCase()}</div>
                <div>${JSON.stringify(content, null, 2)}</div>
            `;

        messagesEl.appendChild(messageEl);
        messagesEl.scrollTop = messagesEl.scrollHeight;

        messageCount++;
        document.getElementById("messageCount").textContent = messageCount;

        if (isError) {
          errorCount++;
          document.getElementById("errorCount").textContent = errorCount;
        }
      }

      function updateUptime() {
        if (connectTime) {
          const now = new Date();
          const diff = Math.floor((now - connectTime) / 1000);
          const minutes = Math.floor(diff / 60);
          const seconds = diff % 60;
          document.getElementById("uptime").textContent = `${minutes
            .toString()
            .padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`;
        }
      }

      function connect() {
        const serverUrl = document.getElementById("serverUrl").value;
        const token = document.getElementById("token").value;
        const conversationId = document.getElementById("conversationId").value;

        if (!serverUrl || !token || !conversationId) {
          alert("Please fill in all fields");
          return;
        }

        const wsUrl = `ws://${serverUrl}/v1/conversation/${conversationId}/stream?authorization=${token}`;

        updateStatus("connecting", "Connecting...");

        ws = new WebSocket(wsUrl);

        ws.onopen = function (event) {
          updateStatus("connected", "Connected");
          connectTime = new Date();
          uptimeInterval = setInterval(updateUptime, 1000);

          document.getElementById("connectBtn").disabled = true;
          document.getElementById("disconnectBtn").disabled = false;

          addMessage("websocket", "WebSocket connection opened");
        };

        ws.onmessage = function (event) {
          try {
            const data = JSON.parse(event.data);

            switch (data.type) {
              case "connected":
                addMessage("connected", data);
                break;
              case "initial_message":
                addMessage("initial_message", data.data);
                break;
              case "message_added":
                addMessage("message_added", data.data);
                break;
              case "message_updated":
                addMessage("message_updated", data.data);
                break;
              case "heartbeat":
                addMessage(
                  "heartbeat",
                  { timestamp: data.timestamp },
                  false,
                  true
                );
                break;
              case "error":
                addMessage("error", data, true);
                break;
              default:
                addMessage("unknown", data);
            }
          } catch (error) {
            addMessage(
              "parse_error",
              `Failed to parse message: ${event.data}`,
              true
            );
          }
        };

        ws.onclose = function (event) {
          updateStatus("disconnected", `Disconnected (Code: ${event.code})`);
          connectTime = null;
          if (uptimeInterval) {
            clearInterval(uptimeInterval);
            uptimeInterval = null;
          }

          document.getElementById("connectBtn").disabled = false;
          document.getElementById("disconnectBtn").disabled = true;

          addMessage(
            "websocket",
            `Connection closed: ${event.reason || "No reason provided"}`
          );
        };

        ws.onerror = function (error) {
          addMessage("websocket_error", `WebSocket error occurred`, true);
          console.error("WebSocket error:", error);
        };
      }

      function disconnect() {
        if (ws) {
          ws.close();
          ws = null;
        }
      }

      function clearMessages() {
        document.getElementById("messages").innerHTML = "";
        messageCount = 0;
        errorCount = 0;
        document.getElementById("messageCount").textContent = "0";
        document.getElementById("errorCount").textContent = "0";
      }

      // Handle page unload
      window.addEventListener("beforeunload", function () {
        if (ws) {
          ws.close();
        }
      });
    </script>
  </body>
</html>
